#pragma once

#include "TrayIcon.h"

namespace API {
namespace Win32 {

#define UM_TRAY_NOTIFY				(WM_USER + 535)

//////////////////////////////////////////////////////////////////////
// Tray Icon
//////////////////////////////////////////////////////////////////////

template <class T>
class CTrayIconImpl : public CTrayIcon
{
protected:
	UINT m_uDefaultMenuID;

public:
	CTrayIconImpl(void)
		: m_uDefaultMenuID(0)
	{
	}

	BEGIN_MSG_MAP_EX(CTrayIconImpl)
		MESSAGE_HANDLER_EX(UM_TRAY_NOTIFY, OnTrayNotify)
	END_MSG_MAP()

	BOOL InitTray(UINT uResourceID)
	{
		T* pT = static_cast<T*>(this);

		HICON hIcon = ::LoadIcon( ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(uResourceID) );

		return CTrayIcon::InitTray(pT->m_hWnd, uResourceID, UM_TRAY_NOTIFY, hIcon, GetString(uResourceID));
	}

	void SetDefaultMenuID(UINT uDefaultMenuID)
	{
		m_uDefaultMenuID = uDefaultMenuID;
	}

protected:
	LRESULT OnTrayNotify(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam)
	{
		if (wParam != m_nid.uID)
			return 0;

		T* pT = static_cast<T*>(this);
		if (LOWORD(lParam) == WM_RBUTTONUP)
		{
			CMenu menu;
			if (!menu.LoadMenu(m_nid.uID))
				return 0;

			CMenuHandle popup(menu.GetSubMenu(0));

			PrepareMenu(popup);

			CPoint pos;
			GetCursorPos(&pos);

			SetForegroundWindow(pT->m_hWnd);
			popup.SetMenuDefaultItem(m_uDefaultMenuID, !m_uDefaultMenuID);

			popup.TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, pT->m_hWnd);
			// BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"
			pT->PostMessage(WM_NULL);
		}
		else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
		{
			SetForegroundWindow(pT->m_hWnd);

			if (m_uDefaultMenuID)
				pT->SendMessage(WM_COMMAND, m_uDefaultMenuID, 0);
			else
			{
				CMenu menu;
				if (!menu.LoadMenu(m_nid.uID))
					return 0;

				CMenuHandle popup(menu.GetSubMenu(0));			

				PrepareMenu(popup);

				UINT nItem = popup.GetMenuItemID(0);

				pT->SendMessage(WM_COMMAND, nItem, 0);
			}
		}

		return 0;
	}

	virtual void PrepareMenu(CMenuHandle popup)
	{
	}
};

//////////////////////////////////////////////////////////////////////

}; //namespace Win32
}; //namespace API
